using Microsoft.AspNetCore.Mvc;
using UserManagement.Data;
using UserManagement.Models;
using UserManagement.Util;

namespace UserManagement.Services;

public class FileService : IFileService
{
    private readonly AppDbContext _context;
    private readonly IWebHostEnvironment _env;
    private readonly string _uploadPath;

    public FileService(AppDbContext context, IWebHostEnvironment env, IConfiguration config)
    {
        _context = context;
        _env = env;
        _uploadPath = Path.Combine(_env.ContentRootPath, config["FileStorage:UploadPath"] ?? throw new InvalidOperationException());
        if (!Directory.Exists(_uploadPath)) Directory.CreateDirectory(_uploadPath);
    }

    public async Task<FileRecord> UploadFileAsync(IFormFile file)
    {
        var storedFileName = Guid.NewGuid() + Path.GetExtension(file.FileName);
        var filePath = Path.Combine(_uploadPath, storedFileName);

        await using var stream = new FileStream(filePath, FileMode.Create);
        await file.CopyToAsync(stream);

        var fileRecord = new FileRecord
        {
            Id = SnowflakeIdGenerator.CreateId(),
            FileName = file.FileName,
            StoredFileName = storedFileName,
            ContentType = file.ContentType
        };

        _context.FileRecords.Add(fileRecord);
        await _context.SaveChangesAsync();

        return fileRecord;
    }

    public async Task<FileResult?> DownloadFileAsync(int id)
    {
        var fileRecord = await _context.FileRecords.FindAsync(id);
        if (fileRecord == null) return null!;

        var filePath = Path.Combine(_uploadPath, fileRecord.StoredFileName);
        var bytes = await File.ReadAllBytesAsync(filePath);

        return new FileContentResult(bytes, fileRecord.ContentType)
        {
            FileDownloadName = fileRecord.FileName
        };
    }
}